package com.heo.util;

import java.math.BigInteger;

import org.springframework.util.StringUtils;

public class ByteHelper {
	/**
	 * 填充字节数组，将某个字节数组前面填充其他的字节。如果长度不够，则不填充
	 * 
	 * @param srcByteArray
	 * @param fillByte
	 * @param fillLength
	 * @return
	 */
	public static byte[] fillByteArray(byte[] srcByteArray, byte fillByte, int fillLength) {
		if (srcByteArray == null || srcByteArray.length >= fillLength) {
			return srcByteArray;
		}
		byte[] resultArray = new byte[fillLength];
		int index = 0;
		for (int i = 0; i < fillLength; i++) {
			if (i < fillLength - srcByteArray.length) {
				resultArray[i] = fillByte;
			} else {
				resultArray[i] = srcByteArray[index];
				index++;
			}
		}
		return resultArray;
	}

	/**
	 * @Title:hexString2Bytes
	 * @Description:16进制字符串转字节数组，传进来的格式是0A0B0C1F，这样连着的字节，也可以是 0A 0B 0C 1F每个字节有空格
	 * @return 字节数组
	 * @param src 16进制字符串
	 * @return
	 */
	public static byte[] hexStringToBytes(String src) {
		if (StringUtils.isEmpty(src)) {
			return null;
		}
		if (src.indexOf(" ") != -1) {
			src = src.replace(" ", "");
		}
		int l = src.length() / 2;
		byte[] ret = new byte[l];
		for (int i = 0; i < l; i++) {
			ret[i] = (byte) Integer.valueOf(src.substring(i * 2, i * 2 + 2), 16).byteValue();
		}
		return ret;
	}

	/**
	 * 16进制转换成为string类型字符串
	 * 
	 * @param s
	 * @return
	 */
	public static String hexStringToString(String s) {
		if (s == null || s.equals("")) {
			return null;
		}
		s = s.replace(" ", "");
		byte[] baKeyword = new byte[s.length() / 2];
		for (int i = 0; i < baKeyword.length; i++) {
			try {
				baKeyword[i] = (byte) (0xff & Integer.parseInt(s.substring(i * 2, i * 2 + 2), 16));
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		try {
			s = new String(baKeyword, "UTF-8");
			new String();
		} catch (Exception e1) {
			e1.printStackTrace();
		}
		return s;
	}

	// public static byte[] strToByteArray(String commandStr)
	// {
	// try
	// {
	// if (commandStr == null)
	// {
	// return null;
	// }
	// String[] strArray = commandStr.split(",");
	// byte[] result = new byte[strArray.length];
	// for (int i = 0; i < strArray.length; i++)
	// {
	// result[i] = Byte.parseByte(strArray[i]);
	// }
	// return result;
	// }
	// catch (Exception e)
	// {
	// e.printStackTrace();
	// return null;
	// }
	// }

	public static Byte strToByte(String commandStr) {
		try {
			if (commandStr == null) {
				return null;
			}
			return Byte.parseByte(commandStr);
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	/**
	 * 将字符串转换成前面是二进制0的字节数组
	 * 
	 * @param str
	 * @param arrayLength
	 * @return
	 */
	public static byte[] stringToByteArray(String str, int arrayLength) {
		if (str == null || str.length() > arrayLength) {
			return null;
		}
		byte[] newArray = new byte[arrayLength - str.getBytes().length];
		for (int i = 0; i < newArray.length; i++) {
			newArray[i] = (byte) 0x00;
		}
		return margeByte(newArray, str.getBytes(), null, null, null, null, null, null, null, null);
	}

	/**
	 * 将字节转换为string
	 * 
	 * @param bt
	 * @return
	 */
	public static String byteToHexString(byte[] bt) {
		if (bt == null || bt.length == 0) {
			return null;
		}
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < bt.length; i++) {
			int tmp = bt[i] & 0xff;
			String tmpStr = Integer.toHexString(tmp);
			if (tmpStr.length() < 2)
				sb.append("0");
			sb.append(tmpStr + " ");
		}
		return sb.toString().substring(0, sb.toString().length() - 1).toUpperCase();
	}

	/**
	 * 将字节转换为string
	 * 
	 * @param bt
	 * @return
	 */
	public static String byteToHexStringNoSpace(byte[] bt) {
		if (bt == null || bt.length == 0) {
			return null;
		}
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < bt.length; i++) {
			int tmp = bt[i] & 0xff;
			String tmpStr = Integer.toHexString(tmp);
			if (tmpStr.length() < 2)
				sb.append("0");
			sb.append(tmpStr);
		}
		return sb.toString().toUpperCase();
	}

	/**
	 * 将字节转化成short整数
	 * 
	 * @param b:字节数组
	 * @param startIndex:开始转换位置
	 * @param length:要转换的字节数
	 * @return 转换后结果
	 */
	public static short byteToShort(byte[] b, int startIndex, int length) {
		short iRet = 0;
		short iTep;
		for (int i = startIndex; i < startIndex + length && i < b.length; i++) {
			iTep = b[i];
			if (iTep < 0) {
				iTep += 256;
			}
			// iTep = iTep << (iLen-1-(i-iFrom)*8);
			// iRet = iRet | iTep;
			iRet = (short) ((iRet << 8) | iTep);
		}
		return iRet;
	}

	/**
	 * 取字节数组中的子数组
	 * 
	 * @param b
	 * @param startIndex
	 * @param length
	 * @return
	 */
	public static byte[] toSubByteArray(byte[] b, int startIndex, int length) {
		byte[] result = new byte[length];
		int j = 0;
		for (int i = startIndex; i < startIndex + length && i < b.length; i++) {
			result[j] = b[i];
			j++;
		}
		return result;
	}

	/**
	 * 将字节转化成整数
	 * 
	 * @param b:字节数组
	 * @param startIndex:开始转换位置
	 * @param length:要转换的字节数
	 * @return 转换后结果
	 */
	public static int byteToInt(byte[] b, int startIndex, int length) {
		int iRet = 0;
		int iTep;
		for (int i = startIndex; i < startIndex + length && i < b.length; i++) {
			iTep = b[i];
			if (iTep < 0) {
				iTep += 256;
			}
			// iTep = iTep << (iLen-1-(i-iFrom)*8);
			// iRet = iRet | iTep;
			iRet = (iRet << 8) | iTep;
		}
		return iRet;
	}

	/**
	 * 将字节转化成字符串
	 * 
	 * @param b:转换后存放结果的字节数组
	 * @param startIndex:存放字节起始位置
	 * @param length:将字符串转换成的字节数
	 * @param bCut:字符串的头部要切除的字符
	 */
	public static String byteToString(byte[] b, int startIndex, int length, byte bCut) {
		if (b == null || startIndex + length > b.length) {
			return null;
		}
		if (length < 1) {
			return "";
		}

		String str = new String(b, startIndex, length);
		if (str == null || str.length() == 0) {
			return "";
		}
		int i = 0;
		while (str.charAt(i) == (char) bCut) {
			i++;
		}
		return str.substring(i);
	}

	/**
	 * 把多个字节数组合并成一个
	 * 
	 * @param b1
	 * @param b2
	 * @return
	 */
	public static byte[] margeByte(byte[]... byteArray) {
		if (byteArray == null || byteArray.length == 0) {
			return new byte[0];
		}
		int arrayLength = 0;
		// 先获得参数的个数，然后找到每个参数中的内容长度
		for (int i = 0; i < byteArray.length; i++) {
			if (byteArray[i] != null) {
				arrayLength = arrayLength + byteArray[i].length;
			}
		}
		byte[] newByteArray = new byte[arrayLength];
		int index = 0;
		for (int i = 0; i < byteArray.length; i++) {
			byte[] innerArray = byteArray[i];
			if (innerArray != null) {
				for (int j = 0; j < innerArray.length; j++) {
					newByteArray[index] = innerArray[j];
					index++;
				}
			}
		}
		return newByteArray;
	}

	/*
	 * 将int转为低字节在后，高字节在前的byte数组 b[0] = 11111111(0xff) & 01100001 b[1] =
	 * 11111111(0xff) & 00000000 b[2] = 11111111(0xff) & 00000000 b[3] =
	 * 11111111(0xff) & 00000000
	 */
	public static byte[] intToByteArray(int value) {
		byte[] src = new byte[4];
		src[0] = (byte) ((value >> 24) & 0xFF);
		src[1] = (byte) ((value >> 16) & 0xFF);
		src[2] = (byte) ((value >> 8) & 0xFF);
		src[3] = (byte) (value & 0xFF);
		return src;
	}

	public static byte intToByte(int value) {
		return (byte) value;
	}

	/*
	 * 将int转为低字节在后，高字节在前的byte数组 b[0] = 11111111(0xff) & 01100001 b[1] =
	 * 11111111(0xff) & 00000000 b[2] = 11111111(0xff) & 00000000 b[3] =
	 * 11111111(0xff) & 00000000
	 */
	public static byte[] shortToByteArray(short value) {
		byte[] src = new byte[2];
		src[0] = (byte) ((value >> 8) & 0xFF);
		src[1] = (byte) (value & 0xFF);
		return src;
	}

	/*
	 * 将int转为低字节在后，高字节在前的byte数组 b[0] = 11111111(0xff) & 01100001 b[1] =
	 * 11111111(0xff) & 00000000 b[2] = 11111111(0xff) & 00000000 b[3] =
	 * 11111111(0xff) & 00000000
	 */
	public static byte[] longToByteArray(long value) {
		byte[] result = new byte[8];
		result[0] = (byte) (value >>> 56);// 取最高8位放到0下标
		result[1] = (byte) (value >>> 48);// 取最高8位放到0下标
		result[2] = (byte) (value >>> 40);// 取最高8位放到0下标
		result[3] = (byte) (value >>> 32);// 取最高8位放到0下标
		result[4] = (byte) (value >>> 24);// 取最高8位放到0下标
		result[5] = (byte) (value >>> 16);// 取次高8为放到1下标
		result[6] = (byte) (value >>> 8); // 取次低8位放到2下标
		result[7] = (byte) (value); // 取最低8位放到3下标
		return result;
	}

	/**
	 * 把int转换为16进制字符串
	 * 
	 * @param value
	 * @return
	 */
	public static String intToHexString(int value) {
		return byteToHexString(intToByteArray(value));
	}

	public static String intToHexString(int value, int length) {
		String hex = Integer.toHexString(value);
		StringBuilder sBuilder = new StringBuilder();
		if (hex.length() < length) {
			int c = length - hex.length();
			for (int i = 0; i < c; i++) {
				sBuilder.append("0");
			}
		}
		return sBuilder.append(hex).toString().toUpperCase();
	}

	public static String floatToHexString(float value, int length) {
		String hex = "";
		if (value > 0) {
			hex = Integer.toHexString(Float.floatToIntBits(value));
			if (hex.length() - length > 0) {
				hex = hex.substring(0, length);
			}
		} else {
			for (int i = 0; i < length; i++) {
				hex = hex + "0";
			}
		}
		return hex.toUpperCase();
	}

	/**
	 * 把short转换为16进制字符串
	 * 
	 * @param value
	 * @return
	 */
	public static String shortToHexString(short value) {
		return byteToHexStringNoSpace(shortToByteArray(value));
	}

	/**
	 * 把long转换为16进制字符串
	 * 
	 * @param value
	 * @return
	 */
	public static String longToHexString(long value) {
		return byteToHexString(longToByteArray(value));
	}

	/**
	 * 16进制转2进制 返回字符串
	 * 
	 * @param hexString
	 * @return
	 */
	public static String hexString2binaryString(String hexString) {
		if (hexString == null || hexString.length() % 2 != 0)
			return null;
		String bString = "", tmp;
		for (int i = 0; i < hexString.length(); i++) {
			tmp = "0000" + Integer.toBinaryString(Integer.parseInt(hexString.substring(i, i + 1), 16));
			bString += tmp.substring(tmp.length() - 4);
		}
		return bString;
	}

	/**
	 * 2进制转16进制 返回字符串
	 * 
	 * @param bString
	 * @return
	 */
	public static String binaryString2hexString(String bString) {
		if (bString == null || bString.equals("") || bString.length() % 8 != 0)
			return null;
		StringBuffer tmp = new StringBuffer();
		int iTmp = 0;
		for (int i = 0; i < bString.length(); i += 4) {
			iTmp = 0;
			for (int j = 0; j < 4; j++) {
				iTmp += Integer.parseInt(bString.substring(i + j, i + j + 1)) << (4 - j - 1);
			}
			tmp.append(Integer.toHexString(iTmp));
		}
		return tmp.toString();
	}

	public static int binary2Int(String binaryString) {
		return Integer.parseInt(binaryString, 2);
	}

	public static String stringReplace(String src, String srcReplace, String replace) {
		if (StringUtils.isEmpty(src)) {
			return null;
		}
		src = src.replaceAll(srcReplace, replace);
		return src;
	}

	public static String hex10To2String(int hex, int length) {
		String hexs = Integer.toBinaryString(hex);
		StringBuilder codeStart = new StringBuilder();
		int size = length - String.valueOf(hexs).length();
		for (int i = 0; i < size; i++) {
			codeStart.append("0");
		}
		codeStart.append(hexs);
		return codeStart.toString();
	}

	public static byte getXor(byte[] datas) {
		byte temp = datas[0];
		for (int i = 1; i < datas.length; i++) {
			temp ^= datas[i];
		}
		return temp;
	}

	public static int hex16ToInt(String hex) {
		Integer x = Integer.parseInt(hex, 16);
		return x;
	}

	public static String strTo16(String s) {
		String str = "";
		for (int i = 0; i < s.length(); i++) {
			int ch = (int) s.charAt(i);
			String hexStr = Integer.toHexString(ch);
			str = str + hexStr;
		}
		return str.toUpperCase();
	}

	/**
	 * 将byte[]转为各种进制的字符串
	 * 
	 * @param bytes byte[]
	 * @param radix 基数可以转换进制的范围，从Character.MIN_RADIX到Character.MAX_RADIX，超出范围后变为10进制
	 * @return 转换后的字符串
	 */
	public static String binary(byte[] bytes, int radix) {
		return new BigInteger(1, bytes).toString(radix);// 这里的1代表正数
	}

	public static void main(String[] args) {
		System.out.println(byteToHexStringNoSpace(hexStringToBytes("01020304")));

		System.out.println(intToHexString(0, 4));

		System.out.println(floatToHexString(1, 4));

		System.out.println(makeCheckSum("68130100010A005F6D9C08682102000000"));

		byte[] src = new byte[] { 0x01, 0x02, 0x03, 0x04 };
		System.out.println(byteToHexStringNoSpace(src));

		byte[] xx = fillByteArray(src, (byte) 0x00, 10);
		for (int i = 0; i < xx.length; i++) {
			System.out.println(xx[i]);
		}

		System.out.println("----" + binary2Int("0110"));

		byte[] bytes = new byte[] { 0 };
		System.out.println(byteToHexString(bytes));
		System.out.println(stringReplace("3434397D01", "7D01", "7D"));

		int bodyInt = 5;

		String hex = "000000" + hex10To2String(bodyInt, 10);

		System.out.println(hexString2binaryString(hex));
		System.out.println(binaryString2hexString(hex));

		bytes = new byte[] { 48, 49, 51, 57 };

		String xor = "8001000502018021001306580658010200";
		bytes = hexStringToBytes(xor);
		byte xorByte = getXor(bytes);
		System.out.println(byteToHexString(new byte[] { xorByte }));

		String hexDomain = strTo16("iwmore.com");
		System.out.println(hexDomain + "----" + hexDomain.length());

		System.out.println(ByteHelper.intToByte(10));

		System.out.println(
				ByteHelper.byteToHexStringNoSpace(new byte[] { ByteHelper.intToByte(hexDomain.length() / 2) }));

		Integer x = 20670000;
		String hexi = x.toHexString(x);
		System.out.println(shortToHexString((short) 1));

		byte[] b = { (byte) 0x1, (byte) 0x0, (byte) 0x0, (byte) 0x0 };
		System.out.println(ByteHelper.byteToHexStringNoSpace(b));

		System.out.println(hexString2binaryString("180329093141"));
		byte[] b1 = { (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x4 };

		System.out.println(hexString2binaryString("0004"));
		System.out.println(ByteHelper.hexString2binaryString("0005"));
		byte[] b2 = { (byte) 0x1 };
		System.out.println(byteToHexStringNoSpace(b2));
		System.out.println(strTo16("a"));
		// System.out.println(byteToHexString(bytes));
		// System.out.println(hex16ToInt("539045030860"));

		System.out.println(bcd2Str(hexStringToBytes("020180210013")));
	}

	/**
	 * byte数组转换为二进制字符串,每个字节以","隔开
	 **/
	public static String conver2HexStr(byte[] b) {
		StringBuffer result = new StringBuffer();
		for (int i = 0; i < b.length; i++) {
			result.append(Long.toString(b[i] & 0xff, 2) + ",");
		}
		return result.toString().substring(0, result.length() - 1);
	}

	/**
	 * @函数功能: BCD码转为10进制串(阿拉伯数据)
	 * @输入参数: BCD码
	 * @输出结果: 10进制串
	 */
	public static String bcd2Str(byte[] bytes) {
		StringBuffer temp = new StringBuffer(bytes.length * 2);
		for (int i = 0; i < bytes.length; i++) {
			temp.append((byte) ((bytes[i] & 0xf0) >>> 4));
			temp.append((byte) (bytes[i] & 0x0f));
		}
		return temp.toString().substring(0, 1).equalsIgnoreCase("0") ? temp.toString().substring(1) : temp.toString();
	}

	public static byte[] checkSum(byte[] packet, String pass) {
		byte[] pktData = packet;
		byte[] key = ByteHelper.hexStringToBytes(pass);
		byte[] checksum = new byte[2];
		pktData[3] = pktData[4] = 0;
		byte[] sum = new byte[] { 0, 0, 0, 0 };
		for (int j = 0; j < 4; j++) {
			for (int i = j; i < pktData.length; i += 4) {
				sum[j] += pktData[i];
			}
		}
		checksum[0] = pktData[3] = (byte) (sum[2] + sum[3] + key[3] + key[2]);
		checksum[1] = pktData[4] = (byte) (sum[1] + sum[0] + key[0] + key[1] + pktData[3]);
//		check = ByteHelper.byteToHexStringNoSpace(checksum);
//		checkSum = checksum;
		return checksum;
	}

	public static String makeCheckSum(String data) {
		if (data == null || data.equals("")) {
			return "";
		}
		int total = 0;
		int len = data.length();
		int num = 0;
		while (num < len) {
			String s = data.substring(num, num + 2);
			total += Integer.parseInt(s, 16);
			num = num + 2;
		}
		/**
		 * 用256求余最大是255，即16进制的FF
		 */
		int mod = total % 256;
		String hex = Integer.toHexString(mod);
		len = hex.length();
		// 如果不够校验位的长度，补0,这里用的是两位校验
		if (len < 2) {
			hex = "0" + hex;
		}
		return hex.toUpperCase();
	}

	public static String strReversal(String code) {
		if (Utils.checkNull(code)) {
			StringBuilder sBuilder = new StringBuilder();
			int length = code.length() / 2;
			for (int i = length; i > 0; i--) {
				sBuilder.append(code.substring((i - 1) * 2, i * 2));
			}
			return sBuilder.toString();
		}
		return "";
	}

	/**
	 * 字符串转换为Ascii
	 * 
	 * @param value
	 * @return
	 */
	public static String stringToAscii(String value) {
		StringBuffer sbu = new StringBuffer();
		char[] chars = value.toCharArray();
		for (int i = 0; i < chars.length; i++) {
//			if (i != chars.length - 1) {
//				sbu.append((int) chars[i]).append(",");
//			} else {
			sbu.append((int) chars[i]);
//			}
		}
		return sbu.toString();
	}

	// 字符串转换为ascii
	public static String stringToAsciiHexString(String content) {
		String result = "";
		int max = content.length();
		for (int i = 0; i < max; i++) {
			char c = content.charAt(i);
			int b = (int) c;
			result = result + intToHexString(b, 2);
		}
		return result;
	}
}
